﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FinosLibrary;
using System.Collections.ObjectModel;
using System.IO;
using System.Net.Sockets;
using System.Reflection;
using System.Windows.Controls;
using System.Windows;
using FinosAdmin;
namespace FinosAdmin.Logics {
    [MessageProcess]
    class AppInfo : ModelLogic {
        public ObservableCollection<FinosApp> FinosApps { get; set; }
        public string AppPath { get { return Selection == null ? "" : Selection.data.path; } set { } }
        public string AppName { get { return Selection == null ? "" : Selection.data.name; } set { } }
        
        private FinosApp selection;
        public FinosApp Selection {
            get { return selection; }
            set {
                selection = value as FinosApp;
                this.NotifyPropertyChanged(x => x.AppPath);
                this.NotifyPropertyChanged(x => x.AppName);
                this.NotifyPropertyChanged(x => x.Selection);
                call("GetInstanceList", AppName);
            }
        }
        [MessageMethod]
        public override void NetConnection_Connected() {
            base.NetConnection_Connected();
            call("GetAppList");
        }
        [MessageMethod]
        public override void NetConnection_Disconnected(string reason) {
            base.NetConnection_Disconnected(reason);
        }
        [MessageMethod]
        public void GotAppList(string[] apps) {
            if (FinosApps == null) {
                FinosApps = new ObservableCollection<FinosApp>();
            }
            FinosApps = new ObservableCollection<FinosApp>(FinosApps.Where(app => apps.Contains(app.data.name)));
            var needAdds = apps.Where(name => FinosApps.Where(app => name == app.data.name).Count() == 0);
            FinosApps = new ObservableCollection<FinosApp>(FinosApps.Concat(needAdds.Select(needAdd => new FinosApp(new AppData { name = needAdd }))));
            this.NotifyPropertyChanged(x => x.FinosApps);
            if (Selection == null) Selection = FinosApps[0];
            else if (!FinosApps.Contains(Selection)) Selection = null;
        }
        [MessageMethod]
        public void GotInstanceList(Package p) {
            p = p.getBody<Package>();
            if (Selection.data.name == p.head) {
                string[] names = p.getBody<string[]>();
                Selection.data.instances = new ObservableCollection<AppData.AppInstance>(new AppData.AppInstance[] { new AppData.AppInstance { name = "自定义属性页" } }.Concat(names.Select(name => new AppData.AppInstance { name = name })));
                Selection.data.NotifyPropertyChanged(x => x.instances);
            }
        }
        [MessageMethod]
        public void CreateApp(string[] arg) {
            byte[] bytes = File.ReadAllBytes(arg[1]);
            string appname = arg[0];
            var selectedApp = FinosApps.SingleOrDefault(app => app.data.name == appname);
            if (selectedApp == null) {
                selectedApp = new FinosApp(new AppData { name = appname, path = arg[1] });
                FinosApps.Add(selectedApp);
            } else {
                selectedApp.data.path = arg[1];
            }
            call("CreateAppBegin", appname);
            send(bytes);
        }
        [MessageMethod]
        public void DeleteApp(string appName) {
            call("DeleteApp", appName);
        }
        [MessageMethod]
        public void TraceMessage(string[] arg) {
            string theApp = arg[0].Split('/')[0];
            string theInstance = arg[0].Split('/')[1];
            string msg = arg[1];
            var selectedApp = FinosApps.SingleOrDefault(app => app.data.name == theApp);
            if (selectedApp != null) {
                selectedApp.data.instances.Single(x => x.name == theInstance).log += msg + "\n";
                selectedApp.data.NotifyPropertyChanged(x => x.AppLog);
            }
        }
        [MessageMethod]
        public void GetAppClients(string name) {
            call("GetAppClients", name);
        }
        [MessageMethod]
        public void GotAppClients(string[] arg) {
            Selection.data.selection.clients = new ObservableCollection<string>(arg);
            Selection.data.NotifyPropertyChanged(x => x.AppClients);
        }
        [MessageMethod]
        public void AddClient(string[] arg) {
            string theApp = arg[0].Split('/')[0];
            string theInstance = arg[0].Split('/')[1];
            string client = arg[1];
            var selectedApp = FinosApps.SingleOrDefault(app => app.data.name == theApp);
            if (selectedApp != null && selectedApp.data.selection != null && selectedApp.data.selection.name == theInstance) {
                selectedApp.data.AppClients.Add(client);
                selectedApp.data.NotifyPropertyChanged(x => x.AppClients);
            }
        }
        [MessageMethod]
        public void RemoveClient(string[] arg) {
            string theApp = arg[0].Split('/')[0];
            string theInstance = arg[0].Split('/')[1];
            string client = arg[1];
            var selectedApp = FinosApps.SingleOrDefault(app => app.data.name == theApp);
            if (selectedApp != null && selectedApp.data.selection != null && selectedApp.data.selection.name == theInstance) {
                selectedApp.data.AppClients.Remove(client);
                selectedApp.data.NotifyPropertyChanged(x => x.AppClients);
            }
        }
        [MessageMethod]
        public void GetPropertyPage(string appName) {
            if (Selection.data.propertyPage == null) {
                connection.byteHead = "GetingPropertyPage";
                call("GetPropertyPage", appName);
            } else {
                Selection.data.UI = Selection.data.propertyPage;
            }
        }
        [MessageMethod]
        public void GetingPropertyPage(Package p) {
            connection.byteHead = null;
            try {
                Selection.data.propertyPage = AppDomain.CurrentDomain.Load(p.byteBody).CreateInstance(Selection.data.name + ".PropertyPage") as UserControl;
                if (Selection.data.propertyPage == null) {
                    Selection.data.propertyPage = NullPage.getInstance();
                }
                Selection.data.UI = Selection.data.propertyPage;
            } catch (Exception e) {
                Selection.data.UI = e.Message;
            }
        }
        [MessageMethod]
        public void PropertyPagePackage(Package p) {
            Package pp = p.getBody<Package>();
            Package ppp = pp.getBody<Package>();
            string appName = pp.head;
            Logic.doLogic(ppp, appName);
        }
    }
}
